package cn.lili.modules.promotion.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.lili.cache.LockPrefix;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.client.OrderItemClient;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.promotion.entity.dos.BlindboxRuleOrder;
import cn.lili.modules.promotion.entity.dos.BoxMhgoods;
import cn.lili.modules.promotion.entity.dto.BlindboxRuleOrderDTO;
import cn.lili.modules.promotion.entity.vos.BlindboxRuleOrderVO;
import cn.lili.modules.promotion.entity.vos.OrderStatusMhVO;
import cn.lili.modules.promotion.mapper.BlindboxRuleOrderMapper;
import cn.lili.modules.promotion.service.BlindboxRuleOrderService;
import cn.lili.modules.promotion.service.BoxMhgoodsService;
import cn.lili.mybatis.util.PageUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BlindboxRuleOrderServiceImpl extends ServiceImpl<BlindboxRuleOrderMapper, BlindboxRuleOrder> implements BlindboxRuleOrderService {

    @Resource
    private OrderClient orderClient;
    @Resource
    private UserClient userClient;
    @Resource
    private GoodsClient goodsClient;
    @Resource
    private OrderItemClient orderItemClient;
    @Resource
    @Lazy
    private BoxMhgoodsService boxMhgoodsService;
    @Resource
    private RedissonClient redisson;

    @Override
    public List<BlindboxRuleOrderVO> getBySn(String orderNo, String orderItemNo) {
        log.info("wwww  orderNo  == {}, orderItemNo == {} ", orderNo, orderItemNo);
        //延迟2秒查询
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("wwww  StringUtils.isEmpty(orderNo) {} ", orderNo);
        if (StringUtils.isEmpty(orderNo)) {
            return null;
        }
        List<BlindboxRuleOrderVO> resultList = new ArrayList<>();
        log.info("wwww begin tempOrder{} ", orderNo);
        Order tempOrder = orderClient.getBySn(orderNo);
        log.info("wwww end tempOrder{} ", JSONObject.toJSONString(tempOrder));
        orderNo = tempOrder.getSn();

        LambdaQueryWrapper<BlindboxRuleOrder> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(BlindboxRuleOrder::getOrderSn, orderNo);
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(orderItemNo), BlindboxRuleOrder::getOrderItemSn, orderItemNo);
        List<BlindboxRuleOrder> list = baseMapper.selectList(lambdaQueryWrapper);
        log.info("wwww begin baseMapper.selectList{} ", JSONObject.toJSONString(list));
        if (list == null || list.isEmpty()) {
            return null;
        }
        log.info("wwww end baseMapper.selectList");
        //统计次数并返回vo
        Map<String, List<BlindboxRuleOrder>> groupedMap = list.stream().collect(Collectors.groupingBy(BlindboxRuleOrder::getRuleGoodsName));
        for (String ruleGoodsName : groupedMap.keySet()) {
            List<BlindboxRuleOrder> group = groupedMap.get(ruleGoodsName);
            BlindboxRuleOrderVO blindboxRuleOrderVO = new BlindboxRuleOrderVO();
            BeanUtils.copyProperties(group.get(0), blindboxRuleOrderVO);
            blindboxRuleOrderVO.setNum(group.size());
            resultList.add(blindboxRuleOrderVO);
        }
        log.info("resultList == {}", JSONObject.toJSONString(resultList));
        return resultList;
    }
    @Override
    public Page<BlindboxRuleOrderDTO> getUpPrizeList(PageVO page) {
        Page<BlindboxRuleOrderDTO> resultPage = this.baseMapper.getUpPrizeList(PageUtil.initPage(page));

        if (resultPage != null && resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
            List<BlindboxRuleOrderDTO> list = resultPage.getRecords().stream().peek(e -> {
                try {
                    Order tempOrder = orderClient.getBySn(e.getOrderSn());
                    //设置用户头像和昵称
                    User user = userClient.getById(tempOrder.getBuyerId());
                    e.setUserName(user.getNickName());
                    e.setFace(user.getFace());
                } catch (Exception exception) {
                    log.error("订单不存在,不影响返回结果!");
                }
            }).toList();
            resultPage.setRecords(list);
        }
        return resultPage;
    }

    /**
     * 是否盲盒订单
     * 是否支付完成
     */
    @Override
    public OrderStatusMhVO getIsMh(String orderNo) {
        RLock lock = null;
        try {
            lock = redisson.getLock(orderNo);
            lock.tryLock(500, TimeUnit.SECONDS);
            log.info("rrrrrr begin getIsMh == {}", orderNo);
            //延迟2秒查询
//            try {
//                Thread.sleep(2000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
            log.info("rrrrrr 2秒等待结束");
            OrderStatusMhVO orderStatusMhVO = new OrderStatusMhVO();
            orderStatusMhVO.setIsMh(false);
            orderStatusMhVO.setIsPay(false);
            //订单号查询盲盒数据
            log.info("rrrrrr orderClient   getBySn == {}", orderNo);
            Order order = orderClient.getBySn(orderNo);
            log.info("rrrrrr order resul ={}", JSONObject.toJSONString(order));
            if (order == null || StringUtils.isEmpty(order.getId())) {
                log.error("未获取到订单信息 == {}", orderNo);
                throw new RuntimeException("未获取到订单信息");
            }
            log.info("rrrrrr orderItemClient   getByOrderSn == {}", orderNo);
            List<OrderItem> orderItemList = orderItemClient.getByOrderSn(orderNo);
            log.info("rrrrrr orderItemList resul ={}", JSONObject.toJSONString(orderItemList));
            if (CollectionUtil.isNotEmpty(orderItemList)) {
                log.info("rrrrrr 进入if判断");
                String goodsId = orderItemList.get(0).getGoodsId();
                log.info("rrrrrr goodsId == {}", goodsId);
                Goods goods = goodsClient.getById(goodsId);
                log.info("rrrrrr goods ===== {}", JSONObject.toJSONString(goods));
                if (StringUtils.isNotEmpty(goods.getId())) {
                    log.info("rrrrrr begin boxMhgoodsService.getById == {}", goods.getMhId());
                    BoxMhgoods boxMhgoods = boxMhgoodsService.getById(goods.getMhId());
                    log.info("rrrrrr boxMhgoods resul ={}", JSONObject.toJSONString(boxMhgoods));
                    if (boxMhgoods != null && StringUtils.isNotEmpty(boxMhgoods.getId())) {
                        log.info("setIsMh 成功");
                        orderStatusMhVO.setIsMh(true);
                    }
                }
            }

            if (PayStatusEnum.PAID.name().equals(order.getPayStatus())) {
                orderStatusMhVO.setIsPay(true);
            }
            log.info("rrrrrr orderStatusMhVO == {}", JSONObject.toJSONString(orderStatusMhVO));
            return orderStatusMhVO;
        } catch (Exception e) {
            log.info("getIsMh = ", e);
            throw new ServiceException("查询是否支付完成失败");
        } finally {
            if (lock != null) {
                lock.unlock();
                log.info("强制释放锁");
            }
        }
    }
}
